using System;
using System.Linq;
using Kiwi.Container.Activation;
using Kiwi.Container.Registration;
using Kiwi.Container.Scope;

namespace Kiwi.Container
{
    public static class ContainerBuilderExtensions
    {
        public static IContainer CreateContainer(this IContainerBuilder builder)
        {
            return builder.CreateContainer(ContainerScope.Global);
        }

        public static IComponentRegistration RegisterMany(this IContainerBuilder builder,
                                                          params IComponentRegistration[] registrations)
        {
            return new CompositeComponentRegistration(registrations.Select(r => builder.Register(r)));
        }

        public static IComponentRegistration<T> Register<T, C>(this IContainerBuilder builder,
                                                               IComponentActivator<C> activator) where C : T
        {
            return (IComponentRegistration<T>) builder.Register(new ComponentRegistration<T, C>(activator));
        }

        public static IComponentRegistration<T> Register<T>(this IContainerBuilder builder) where T : class
        {
            return builder.Register<T, T>(new BestFitConstructorComponentActivator<T>());
        }

        public static IComponentRegistration<T> Register<T, C>(this IContainerBuilder builder) where C : T
        {
            return builder.Register<T, C>(new BestFitConstructorComponentActivator<C>());
        }

        public static IComponentRegistration<T> Register<T>(this IContainerBuilder builder,
                                                            Func<IComponentResolver, T> creator)
        {
            return builder.Register<T, T>(creator);
        }

        public static IComponentRegistration<T> Register<T, C>(this IContainerBuilder builder,
                                                               Func<IComponentResolver, C> creator) where C : T
        {
            return builder.Register<T, C>(new LambdaComponentActivator<T, C>(creator));
        }
    }
}